package pe.com.bbva.pct.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.faces.model.SelectItem;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import pe.com.bbva.mtrgl.classLoader.AplicacionClassLoader;
import pe.com.bbva.pct.dao.AplicacionDAO;
import pe.com.bbva.pct.dao.FuenteDAO;
import pe.com.bbva.pct.dao.ReglaDAO;
import pe.com.bbva.pct.dao.ReglaFuenteDAO;
import pe.com.bbva.pct.dao.RelacionFuenteEntidadDAO;
import pe.com.bbva.pct.domain.Aplicacion;
import pe.com.bbva.pct.domain.DetalleFuente;
import pe.com.bbva.pct.domain.Fuente;
import pe.com.bbva.pct.domain.Regla;
import pe.com.bbva.pct.domain.ReglaFuente;
import pe.com.bbva.pct.domain.RelacionFuenteEntidad;
import pe.com.bbva.pct.domain.Valor;
import pe.com.bbva.pct.dto.DetalleFuenteDAO;
import pe.com.bbva.pct.dto.ReglaDTO;
import pe.com.bbva.pct.dto.ReglaFuenteDTO;
import pe.com.bbva.pct.dto.RelacionFuenteEntidadDTO;
import pe.com.bbva.pct.service.ReglaService;
import pe.com.bbva.pct.util.ConstantesGenerales;
import pe.com.bbva.pct.util.SelectLabel;
import pe.com.bbva.pct.vo.ReglaVO;

@Service("reglaService")
public class ReglaServiceImpl implements ReglaService{

	
	@Resource(name="reglaDao")
	private ReglaDAO reglaDao;
	
	@Resource(name="fuenteDao")
	private FuenteDAO fuenteDao;
	
	@Resource(name="detalleFuenteDao")
	private DetalleFuenteDAO detalleFuenteDao;
	
	@Resource(name="reglaFuenteDao")
	private ReglaFuenteDAO reglaFuenteDao;
	
	@Resource(name="relacionFuenteEntidadDao")
	private RelacionFuenteEntidadDAO relacionFuenteEntidadDao;
	
	@Resource(name="aplicacionDao")
	private AplicacionDAO aplicacionDao;
	
	
	@Resource(name="aplicacionClassLoader")
	private AplicacionClassLoader aplicacionClassLoader;
	
	
	@Transactional(readOnly = true)
	@Override
	public int cantidadTotalObjetos(Object reglaVO) throws Exception{				
		return reglaDao.cantidadTotalValores((ReglaVO) reglaVO);
	}	
	
	
	@Transactional(readOnly = true)
	@Override
	public List<Object> buscarObjetosPaginados(int first, int pageSize,Object reglaVO) throws Exception{		
		List<Object> listaReglasDTO =new ArrayList<Object>(); 
		List<Regla> listaReglasDomain =new ArrayList<Regla>(); 
		try {
			listaReglasDomain=reglaDao.obtenerValoresPaginado(first, pageSize,(ReglaVO) reglaVO);
			
			Integer intNumeroItem=1;
			for(Regla regla:listaReglasDomain){
				ReglaDTO reglaDTO=new ReglaDTO();
				reglaDTO.setIdRegla(regla.getIdRegla().toString());
				reglaDTO.setNombre(regla.getNombre());
				reglaDTO.setNombreGuvnor(regla.getNombreGuvnor());
				reglaDTO.setItem(intNumeroItem);
				listaReglasDTO.add(reglaDTO);
				intNumeroItem++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaReglasDTO;		
	}
	
	@Transactional(readOnly = true)
	@Override
	public List<SelectItem> obtenerListaFuentes(Long tipo) throws Exception{
		List<SelectItem> listadoFuentes = new ArrayList<SelectItem>();
		try {
			List<Fuente> fuentes = new ArrayList<Fuente>();
			fuentes=fuenteDao.listarFuentes(tipo);
			SelectItem select= new SelectItem();
			select.setValue(Long.parseLong(ConstantesGenerales.VALOR_SELECCIONE));
			select.setLabel(ConstantesGenerales.SELECCIONE);
			listadoFuentes.add(select);
			for(Fuente fuente:fuentes){
				SelectItem selectItem = new SelectItem();
				selectItem.setValue(fuente.getIdFuente());
				selectItem.setLabel(fuente.getNombre());
				listadoFuentes.add(selectItem);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listadoFuentes;
	}
	
	@Transactional(readOnly = true)
	@Override
	public List<SelectLabel> obtenerListaEntidades(Long idAplicacion) throws Exception{
		List<SelectLabel> listadoEntidades = new ArrayList<SelectLabel>();
		try {
			Aplicacion aplicacion = new Aplicacion();
			aplicacion = aplicacionDao.obtenerObjeto(idAplicacion, Aplicacion.class);
			List<String> listaEntidades = aplicacionClassLoader.listaClasesAplicacion(aplicacion.getNombreJar());
			SelectLabel selectLabel1 = new SelectLabel();
			selectLabel1.setIdLabel(ConstantesGenerales.VALOR_SELECCIONE);
			selectLabel1.setLabel(ConstantesGenerales.SELECCIONE);
			listadoEntidades.add(selectLabel1);
			for(String strItem:listaEntidades ){
				SelectLabel selectLabel = new SelectLabel();
				selectLabel.setIdLabel(strItem);
				selectLabel.setLabel(strItem);
				listadoEntidades.add(selectLabel);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listadoEntidades;
	}
	
	
	@Transactional(readOnly = true)
	@Override
	public List<RelacionFuenteEntidadDTO> obtenerCamposFuenteNuevo(Long idFuente) throws Exception{
		List<RelacionFuenteEntidadDTO> listaRelacionFuenteEntidadDTO = new ArrayList<RelacionFuenteEntidadDTO>();
		try {
			List<DetalleFuente> listaCampos=detalleFuenteDao.obtenerDetalleFuente(idFuente);
			Integer contador=1;
			for(DetalleFuente detalleFuente:listaCampos){
				RelacionFuenteEntidadDTO relacionDTO = new RelacionFuenteEntidadDTO();
				relacionDTO.setItem(contador);
				relacionDTO.setIdCampoFuente(detalleFuente.getIdDetalleFuente().toString());
				relacionDTO.setCampoFuente(detalleFuente.getNombreCampo());
				relacionDTO.setCampoEntidad(ConstantesGenerales.VALOR_SELECCIONE);
				listaRelacionFuenteEntidadDTO.add(relacionDTO);
				contador++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaRelacionFuenteEntidadDTO;
	}
	
	@Transactional(readOnly = true)
	@Override
	public List<RelacionFuenteEntidadDTO> obtenerRelaciones(Long idReglaFuente) throws Exception{
		List<RelacionFuenteEntidadDTO> listaRelacionFuenteEntidadDTO = new ArrayList<RelacionFuenteEntidadDTO>();
		try {
			List<RelacionFuenteEntidad> listaRelacionFuenteEntidad =  relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(idReglaFuente);
			Integer contador2=1;
			for(RelacionFuenteEntidad relacionFuenteEntidad:listaRelacionFuenteEntidad){
				RelacionFuenteEntidadDTO relacionFuenteEntidadDTO = new RelacionFuenteEntidadDTO();
				
				relacionFuenteEntidadDTO.setIdRelacionFuenteEntidad(relacionFuenteEntidad.getIdRelacionFuenteEntidad().toString());
				relacionFuenteEntidadDTO.setIdReglaFuente(relacionFuenteEntidad.getIdReglaFuente().getIdReglaFuente().toString());
				relacionFuenteEntidadDTO.setId(contador2);
				relacionFuenteEntidadDTO.setItem(contador2);
				relacionFuenteEntidadDTO.setCampoEntidad(relacionFuenteEntidad.getCampoEntidad());
				relacionFuenteEntidadDTO.setIdCampoFuente(relacionFuenteEntidad.getIdDetalleFuente().getIdDetalleFuente().toString());
				relacionFuenteEntidadDTO.setCampoFuente(relacionFuenteEntidad.getCampoFuente());
				relacionFuenteEntidadDTO.setIdEstado(relacionFuenteEntidad.getIdEstado().getIdValor().toString());
				relacionFuenteEntidadDTO.setFueGuardado(true);
				listaRelacionFuenteEntidadDTO.add(relacionFuenteEntidadDTO);
				contador2++;
				}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaRelacionFuenteEntidadDTO;
	}
	
	@Transactional(readOnly = true)
	@Override
	public List<SelectLabel> listarCamposEntidad(String claseEntidad, Long idAplicacion) throws Exception{
		List<SelectLabel> listaCamposEntidad = new ArrayList<SelectLabel>();
		try {
			Aplicacion aplicacion = new Aplicacion();
			aplicacion = aplicacionDao.obtenerObjeto(idAplicacion, Aplicacion.class);
			List<String> listaCampos = aplicacionClassLoader.listaMetodosAplicacion(claseEntidad, aplicacion.getNombreJar());
			SelectLabel selectLabel1 = new SelectLabel();
			selectLabel1.setIdLabel(ConstantesGenerales.VALOR_SELECCIONE);
			selectLabel1.setLabel(ConstantesGenerales.SELECCIONE);
			listaCamposEntidad.add(selectLabel1);
			for(String strItem:listaCampos ){
				SelectLabel selectLabel = new SelectLabel();
				selectLabel.setIdLabel(strItem);
				selectLabel.setLabel(strItem);
				listaCamposEntidad.add(selectLabel);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}	
		return listaCamposEntidad;
		}
	
	@Transactional(readOnly = true)
	@Override
	public ReglaDTO obtenerRegla(Long idReglaSeleccionada) throws Exception{
		ReglaDTO reglaDTO = new ReglaDTO();
		try {
			Regla regla = new Regla();
			regla=reglaDao.obtenerObjeto(idReglaSeleccionada, Regla.class);
			reglaDTO.setIdRegla(regla.getIdRegla().toString());
			reglaDTO.setIdAplicacion(regla.getIdAplicacion().getIdAplicacion().toString());
			reglaDTO.setNombre(regla.getNombre());
			reglaDTO.setNombreGuvnor(regla.getNombreGuvnor());
			reglaDTO.setDescripcion(regla.getDescripcion());
			reglaDTO.setIdEstado(regla.getIdEstado().getIdValor().toString());
			reglaDTO.setIdTipoEjecucion(regla.getIdTipoEjecucion().getIdValor().toString());
			List<ReglaFuente> listaReglaFuente = reglaFuenteDao.obtenerReglaFuente(regla.getIdRegla());
			Integer contador=1;
			for(ReglaFuente reglaFuente:listaReglaFuente){
				ReglaFuenteDTO reglaFuenteDTO = new ReglaFuenteDTO();
				reglaFuenteDTO.setItem(contador);
				reglaFuenteDTO.setId(contador);
				reglaFuenteDTO.setIdFuente(reglaFuente.getIdFuente().getIdFuente().toString());
				reglaFuenteDTO.setClaseEntidad(reglaFuente.getClaseEntidad());
				reglaFuenteDTO.setIdReglaFuente(reglaFuente.getIdReglaFuente().toString());
				reglaFuenteDTO.setIdEstado(reglaFuente.getIdEstado().getIdValor().toString());
				reglaFuenteDTO.setIdTipoFuente(reglaFuente.getIdTipoFuente().getIdValor().toString());
				List<RelacionFuenteEntidad> listaRelacionFuenteEntidad =  relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(reglaFuente.getIdReglaFuente());
				Integer contador2=1;
				for(RelacionFuenteEntidad relacionFuenteEntidad:listaRelacionFuenteEntidad){
					RelacionFuenteEntidadDTO relacionFuenteEntidadDTO = new RelacionFuenteEntidadDTO();
					
					relacionFuenteEntidadDTO.setIdRelacionFuenteEntidad(relacionFuenteEntidad.getIdRelacionFuenteEntidad().toString());
					relacionFuenteEntidadDTO.setIdReglaFuente(relacionFuenteEntidad.getIdReglaFuente().getIdReglaFuente().toString());
					relacionFuenteEntidadDTO.setId(contador2);
					relacionFuenteEntidadDTO.setItem(contador2);
					relacionFuenteEntidadDTO.setCampoEntidad(relacionFuenteEntidad.getCampoEntidad());
					relacionFuenteEntidadDTO.setIdCampoFuente(relacionFuenteEntidad.getIdDetalleFuente().getIdDetalleFuente().toString());
					relacionFuenteEntidadDTO.setCampoFuente(relacionFuenteEntidad.getCampoFuente());
					relacionFuenteEntidadDTO.setIdEstado(relacionFuenteEntidad.getIdEstado().getIdValor().toString());
					relacionFuenteEntidadDTO.setFueGuardado(true);
					reglaFuenteDTO.getListaRelacionFuenteEntidad().add(relacionFuenteEntidadDTO);
					
					contador2++;
					}
				contador++;
				
				if(reglaFuente.getIdTipoFuente().getIdValor().toString().equals(ConstantesGenerales.TIPO_FUENTE_SALIDA)){
					reglaDTO.setReglaFuenteSalida(reglaFuenteDTO);
				}else if(reglaFuente.getIdTipoFuente().getIdValor().toString().equals(ConstantesGenerales.TIPO_FUENTE_ENTRADA)){
					reglaDTO.getListaFuentesEntrada().add(reglaFuenteDTO);
				}
				
			}
			
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return reglaDTO;
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void insertarRegla(ReglaDTO reglaDTO) throws Exception{
		try {
			if(reglaDTO.getIdTipoEjecucion().toString().equals(ConstantesGenerales.TIPO_SINCRONA)){
				Regla regla= new Regla();
				regla.setNombre(reglaDTO.getNombre().trim());
				regla.setNombreGuvnor(reglaDTO.getNombreGuvnor());
				regla.setDescripcion(reglaDTO.getDescripcion().trim());
				regla.setIdTipoEjecucion(new Valor());
				regla.getIdTipoEjecucion().setIdValor(Long.parseLong(reglaDTO.getIdTipoEjecucion()));
				regla.setIdAplicacion(new Aplicacion());
				regla.getIdAplicacion().setIdAplicacion(Long.parseLong(reglaDTO.getIdAplicacion()));
				regla.setIdEstado(new Valor());
				regla.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
				regla = reglaDao.insertarObjetoReturnId(regla);
			}else if(reglaDTO.getIdTipoEjecucion().toString().equals(ConstantesGenerales.TIPO_ASINCRONA)){
				Regla regla= new Regla();
				regla.setNombre(reglaDTO.getNombre().trim());
				regla.setNombreGuvnor(reglaDTO.getNombreGuvnor());
				regla.setDescripcion(reglaDTO.getDescripcion().trim());
				regla.setIdTipoEjecucion(new Valor());
				regla.getIdTipoEjecucion().setIdValor(Long.parseLong(reglaDTO.getIdTipoEjecucion()));
				regla.setIdAplicacion(new Aplicacion());
				regla.getIdAplicacion().setIdAplicacion(Long.parseLong(reglaDTO.getIdAplicacion()));
				regla.setIdEstado(new Valor());
				regla.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
				regla = reglaDao.insertarObjetoReturnId(regla);
				
				for(ReglaFuenteDTO reglaFuenteDTO:reglaDTO.getListaFuentesEntrada()){
					ReglaFuente reglaFuente = new ReglaFuente();
					reglaFuente.setIdRegla(new Regla());
					reglaFuente.getIdRegla().setIdRegla(regla.getIdRegla());
					reglaFuente.setClaseEntidad(reglaFuenteDTO.getClaseEntidad().trim());
					reglaFuente.setIdFuente(new Fuente());
					reglaFuente.getIdFuente().setIdFuente(Long.parseLong(reglaFuenteDTO.getIdFuente()));
					reglaFuente.setClaseEntidad(reglaFuenteDTO.getClaseEntidad());
					reglaFuente.setIdTipoFuente(new Valor());
					reglaFuente.getIdTipoFuente().setIdValor(Long.parseLong(reglaFuenteDTO.getIdTipoFuente()));
					reglaFuente.setIdEstado(new Valor());
					reglaFuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
					reglaFuente = reglaFuenteDao.insertarObjetoReturnId(reglaFuente);
					
					for(RelacionFuenteEntidadDTO relacionFuenteEntidadDTO: reglaFuenteDTO.getListaRelacionFuenteEntidad()){
						RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
						relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
						relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
						relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
						relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
						relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
						relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuente.getIdReglaFuente());
						relacionFuenteEntidad.setIdEstado(new Valor());
						relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
						relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
					}
				}
				
				ReglaFuente reglaFuenteSalida = new ReglaFuente();
				reglaFuenteSalida.setIdRegla(new Regla());
				reglaFuenteSalida.getIdRegla().setIdRegla(regla.getIdRegla());
				
				reglaFuenteSalida.setIdFuente(new Fuente());
				reglaFuenteSalida.getIdFuente().setIdFuente(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdFuente()));
				if(reglaDTO.getReglaFuenteSalida().getClaseEntidad().equals(ConstantesGenerales.VALOR_SELECCIONE)){
					reglaDTO.getReglaFuenteSalida().setClaseEntidad(ConstantesGenerales.VALOR_VACIO);
				}else{
					reglaFuenteSalida.setClaseEntidad(reglaDTO.getReglaFuenteSalida().getClaseEntidad());
				}
				
				reglaFuenteSalida.setIdTipoFuente(new Valor());
				reglaFuenteSalida.getIdTipoFuente().setIdValor(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdTipoFuente()));
				reglaFuenteSalida.setIdEstado(new Valor());
				reglaFuenteSalida.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
				reglaFuenteSalida = reglaFuenteDao.insertarObjetoReturnId(reglaFuenteSalida);
				
				for(RelacionFuenteEntidadDTO relacionFuenteEntidadDTO: reglaDTO.getReglaFuenteSalida().getListaRelacionFuenteEntidad()){
					RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
					relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
					relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
					relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
					relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
					relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
					relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuenteSalida.getIdReglaFuente());
					relacionFuenteEntidad.setIdEstado(new Valor());
					relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
					relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public void actualizarRegla(ReglaDTO reglaDTO) throws Exception{
		try {
			if(reglaDTO.getIdTipoEjecucion().toString().equals(ConstantesGenerales.TIPO_SINCRONA)){
				Regla regla= new Regla();
				regla.setIdRegla(Long.parseLong(reglaDTO.getIdRegla()));
				regla.setNombre(reglaDTO.getNombre().trim());
				regla.setNombreGuvnor(reglaDTO.getNombreGuvnor());
				regla.setDescripcion(reglaDTO.getDescripcion().trim());
				regla.setIdTipoEjecucion(new Valor());
				regla.getIdTipoEjecucion().setIdValor(Long.parseLong(reglaDTO.getIdTipoEjecucion()));
				regla.setIdAplicacion(new Aplicacion());
				regla.getIdAplicacion().setIdAplicacion(Long.parseLong(reglaDTO.getIdAplicacion()));
				regla.setIdEstado(new Valor());
				regla.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
				regla = reglaDao.actualizarObjeto(regla);
				
				List<ReglaFuente> listaReglaFuente = reglaFuenteDao.obtenerReglaFuente(regla.getIdRegla());
				for(ReglaFuente reglaFuente:listaReglaFuente){
					reglaFuente.setIdEstado(new Valor());
					reglaFuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ELIMINADO_VALOR_LISTADO);
					reglaFuenteDao.actualizarObjeto(reglaFuente);
					
					List<RelacionFuenteEntidad> listaRelacionFuenteEntidad =  relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(reglaFuente.getIdReglaFuente());
					for(RelacionFuenteEntidad relacionFuenteEntidad:listaRelacionFuenteEntidad){
						relacionFuenteEntidad.setIdEstado(new Valor());
						relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ELIMINADO_VALOR_LISTADO);
						relacionFuenteEntidadDao.actualizarObjeto(relacionFuenteEntidad);
					}
				}
				
			}else if(reglaDTO.getIdTipoEjecucion().toString().equals(ConstantesGenerales.TIPO_ASINCRONA)){
				Regla regla= new Regla();
				regla.setIdRegla(Long.parseLong(reglaDTO.getIdRegla()));
				regla.setNombre(reglaDTO.getNombre().trim());
				regla.setNombreGuvnor(reglaDTO.getNombreGuvnor());
				regla.setDescripcion(reglaDTO.getDescripcion().trim());
				regla.setIdTipoEjecucion(new Valor());
				regla.getIdTipoEjecucion().setIdValor(Long.parseLong(reglaDTO.getIdTipoEjecucion()));
				regla.setIdAplicacion(new Aplicacion());
				regla.getIdAplicacion().setIdAplicacion(Long.parseLong(reglaDTO.getIdAplicacion()));
				regla.setIdEstado(new Valor());
				regla.getIdEstado().setIdValor(Long.parseLong(reglaDTO.getIdEstado()));
				
				
				regla = reglaDao.actualizarObjeto(regla);
				
				for(ReglaFuenteDTO reglaFuenteDTO:reglaDTO.getListaFuentesEntrada()){
					
					if(reglaFuenteDTO.getIdReglaFuente()==null || reglaFuenteDTO.getIdReglaFuente().trim().equals(ConstantesGenerales.VALOR_VACIO)){
						
						ReglaFuente reglaFuente = new ReglaFuente();
						reglaFuente.setIdRegla(new Regla());
						reglaFuente.getIdRegla().setIdRegla(regla.getIdRegla());
						reglaFuente.setClaseEntidad(reglaFuenteDTO.getClaseEntidad().trim());
						reglaFuente.setIdFuente(new Fuente());
						reglaFuente.getIdFuente().setIdFuente(Long.parseLong(reglaFuenteDTO.getIdFuente()));
						reglaFuente.setClaseEntidad(reglaFuenteDTO.getClaseEntidad());
						reglaFuente.setIdTipoFuente(new Valor());
						reglaFuente.getIdTipoFuente().setIdValor(Long.parseLong(reglaFuenteDTO.getIdTipoFuente()));
						reglaFuente.setIdEstado(new Valor());
						reglaFuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
						reglaFuente = reglaFuenteDao.insertarObjetoReturnId(reglaFuente);
						
						for(RelacionFuenteEntidadDTO relacionFuenteEntidadDTO: reglaFuenteDTO.getListaRelacionFuenteEntidad()){
							RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
							relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
							relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
							relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
							relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
							relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
							relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuente.getIdReglaFuente());
							relacionFuenteEntidad.setIdEstado(new Valor());
							relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
							relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
						}
						
					}else{
						ReglaFuente reglaFuente = new ReglaFuente();
						reglaFuente.setIdReglaFuente(Long.parseLong(reglaFuenteDTO.getIdReglaFuente()));
						reglaFuente.setIdRegla(new Regla());
						reglaFuente.getIdRegla().setIdRegla(regla.getIdRegla());
						reglaFuente.setClaseEntidad(reglaFuenteDTO.getClaseEntidad().trim());
						reglaFuente.setIdFuente(new Fuente());
						reglaFuente.getIdFuente().setIdFuente(Long.parseLong(reglaFuenteDTO.getIdFuente()));
						reglaFuente.setClaseEntidad(reglaFuenteDTO.getClaseEntidad());
						reglaFuente.setIdTipoFuente(new Valor());
						reglaFuente.getIdTipoFuente().setIdValor(Long.parseLong(reglaFuenteDTO.getIdTipoFuente()));
						reglaFuente.setIdEstado(new Valor());
						reglaFuente.getIdEstado().setIdValor(Long.parseLong(reglaFuenteDTO.getIdEstado()));
						reglaFuente = reglaFuenteDao.actualizarObjeto(reglaFuente);
						
						
						for(RelacionFuenteEntidadDTO relacionFuenteEntidadDTO: reglaFuenteDTO.getListaRelacionFuenteEntidad()){
							
							if(relacionFuenteEntidadDTO.getIdRelacionFuenteEntidad()==null || relacionFuenteEntidadDTO.getIdRelacionFuenteEntidad().trim().equals(ConstantesGenerales.VALOR_VACIO)){
								RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
								relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
								relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
								relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
								relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
								relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
								relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuente.getIdReglaFuente());
								relacionFuenteEntidad.setIdEstado(new Valor());
								relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
								relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
							}else {
								RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
								relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
								relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
								relacionFuenteEntidad.setIdRelacionFuenteEntidad(Long.parseLong(relacionFuenteEntidadDTO.getIdRelacionFuenteEntidad()));
								relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
								relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
								relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
								relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuente.getIdReglaFuente());
								relacionFuenteEntidad.setIdEstado(new Valor());
								relacionFuenteEntidad.getIdEstado().setIdValor(Long.parseLong(relacionFuenteEntidadDTO.getIdEstado()));
								relacionFuenteEntidadDao.actualizarObjeto(relacionFuenteEntidad);
							}
							
						}
						
					}
					
					
				}
				
				
				ReglaFuente reglaFuenteSalida = new ReglaFuente();
				if(reglaDTO.getReglaFuenteSalida().getIdReglaFuente()==null || reglaDTO.getReglaFuenteSalida().getIdReglaFuente().trim().equals(ConstantesGenerales.VALOR_VACIO)){
					
					
					reglaFuenteSalida.setIdRegla(new Regla());
					reglaFuenteSalida.getIdRegla().setIdRegla(regla.getIdRegla());
					reglaFuenteSalida.setClaseEntidad(reglaDTO.getReglaFuenteSalida().getClaseEntidad());
					reglaFuenteSalida.setIdFuente(new Fuente());
					reglaFuenteSalida.getIdFuente().setIdFuente(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdFuente()));
					reglaFuenteSalida.setIdTipoFuente(new Valor());
					reglaFuenteSalida.getIdTipoFuente().setIdValor(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdTipoFuente()));
					reglaFuenteSalida.setIdEstado(new Valor());
					reglaFuenteSalida.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
					if(reglaDTO.getReglaFuenteSalida().getClaseEntidad().endsWith(ConstantesGenerales.VALOR_SELECCIONE)){
						reglaFuenteSalida.setClaseEntidad(ConstantesGenerales.VALOR_VACIO);
					}else{
						reglaFuenteSalida.setClaseEntidad(reglaDTO.getReglaFuenteSalida().getClaseEntidad());
					}
					
					reglaFuenteSalida = reglaFuenteDao.insertarObjetoReturnId(reglaFuenteSalida);
					
					for(RelacionFuenteEntidadDTO relacionFuenteEntidadDTO: reglaDTO.getReglaFuenteSalida().getListaRelacionFuenteEntidad()){

							RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
							relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
							relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
							relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
							relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
							relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
							relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuenteSalida.getIdReglaFuente());
							relacionFuenteEntidad.setIdEstado(new Valor());
							relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
							relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
					
					}
					
				}else{
					reglaFuenteSalida.setIdReglaFuente(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdReglaFuente()));
					reglaFuenteSalida.setIdRegla(new Regla());
					reglaFuenteSalida.getIdRegla().setIdRegla(regla.getIdRegla());
					
					reglaFuenteSalida.setIdFuente(new Fuente());
					reglaFuenteSalida.getIdFuente().setIdFuente(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdFuente()));
					
					reglaFuenteSalida.setIdTipoFuente(new Valor());
					reglaFuenteSalida.getIdTipoFuente().setIdValor(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdTipoFuente()));
					reglaFuenteSalida.setIdEstado(new Valor());
					reglaFuenteSalida.getIdEstado().setIdValor(Long.parseLong(reglaDTO.getReglaFuenteSalida().getIdEstado()));
					if(reglaDTO.getReglaFuenteSalida().getClaseEntidad().endsWith(ConstantesGenerales.VALOR_SELECCIONE)){
						reglaFuenteSalida.setClaseEntidad(ConstantesGenerales.VALOR_VACIO);
						
					}else{
						reglaFuenteSalida.setClaseEntidad(reglaDTO.getReglaFuenteSalida().getClaseEntidad());
						
					}
					reglaFuenteSalida = reglaFuenteDao.actualizarObjeto(reglaFuenteSalida);
					
					if(reglaDTO.getReglaFuenteSalida().getClaseEntidad().endsWith(ConstantesGenerales.VALOR_SELECCIONE)){
						List<RelacionFuenteEntidad> lista=relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(reglaFuenteSalida.getIdReglaFuente());
						for(RelacionFuenteEntidad item:lista){
							relacionFuenteEntidadDao.borrarObjeto(item);
						}
					}else{
						for(RelacionFuenteEntidadDTO relacionFuenteEntidadDTO: reglaDTO.getReglaFuenteSalida().getListaRelacionFuenteEntidad()){
							
							if(relacionFuenteEntidadDTO.getIdRelacionFuenteEntidad()==null || relacionFuenteEntidadDTO.getIdRelacionFuenteEntidad().trim().equals(ConstantesGenerales.VALOR_VACIO)){
							
								RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
								relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
								relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
								relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
								relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
								relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
								relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuenteSalida.getIdReglaFuente());
								relacionFuenteEntidad.setIdEstado(new Valor());
								relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
								relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
							}else{
								RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
								relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
								relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(relacionFuenteEntidadDTO.getIdCampoFuente()));
								relacionFuenteEntidad.setIdRelacionFuenteEntidad(Long.parseLong(relacionFuenteEntidadDTO.getIdRelacionFuenteEntidad()));
								relacionFuenteEntidad.setCampoEntidad(relacionFuenteEntidadDTO.getCampoEntidad().trim());
								relacionFuenteEntidad.setCampoFuente(relacionFuenteEntidadDTO.getCampoFuente().trim());
								relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
								relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(reglaFuenteSalida.getIdReglaFuente());
								relacionFuenteEntidad.setIdEstado(new Valor());
								relacionFuenteEntidad.getIdEstado().setIdValor(Long.parseLong(relacionFuenteEntidadDTO.getIdEstado()));
								relacionFuenteEntidadDao.actualizarObjeto(relacionFuenteEntidad);
							
							}
						}
					}
				}
				
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Transactional(rollbackFor = Exception.class)
	@Override
	public List<RelacionFuenteEntidadDTO> actualizarRelaciones(List<RelacionFuenteEntidadDTO> listaRelacionFuenteEntidadDTO, Long idReglaFuente, Long strIdFuente, String strEntidad) throws Exception{
		List<RelacionFuenteEntidadDTO> listaDTO = new ArrayList<RelacionFuenteEntidadDTO>();
		try {
			ReglaFuente reglaFuente= reglaFuenteDao.obtenerObjeto(idReglaFuente, ReglaFuente.class);
			reglaFuente.setIdFuente(new Fuente());
			reglaFuente.getIdFuente().setIdFuente(strIdFuente);
			reglaFuente.setClaseEntidad(strEntidad);
			reglaFuente=reglaFuenteDao.actualizarObjeto(reglaFuente);
			List<RelacionFuenteEntidad> lista=relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(idReglaFuente);
			for(RelacionFuenteEntidad item:lista){
				relacionFuenteEntidadDao.borrarObjeto(item);
			}
			
			for(RelacionFuenteEntidadDTO item:listaRelacionFuenteEntidadDTO){
				RelacionFuenteEntidad relacionFuenteEntidad = new RelacionFuenteEntidad();
				relacionFuenteEntidad.setIdDetalleFuente(new DetalleFuente());
				relacionFuenteEntidad.getIdDetalleFuente().setIdDetalleFuente(Long.parseLong(item.getIdCampoFuente()));
				relacionFuenteEntidad.setCampoEntidad(item.getCampoEntidad().trim());
				relacionFuenteEntidad.setCampoFuente(item.getCampoFuente().trim());
				relacionFuenteEntidad.setIdReglaFuente(new ReglaFuente());
				relacionFuenteEntidad.getIdReglaFuente().setIdReglaFuente(idReglaFuente);
				relacionFuenteEntidad.setIdEstado(new Valor());
				relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ACTIVO_VALOR_LISTADO);
				
				relacionFuenteEntidadDao.insertarObjeto(relacionFuenteEntidad);
			}
			
			lista=relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(idReglaFuente);
			Integer contador2=1;
			for(RelacionFuenteEntidad relacionFuenteEntidad:lista){
				RelacionFuenteEntidadDTO relacionFuenteEntidadDTO = new RelacionFuenteEntidadDTO();
				relacionFuenteEntidadDTO.setIdDetallerFuente(relacionFuenteEntidad.getIdDetalleFuente().getIdDetalleFuente().toString());
				relacionFuenteEntidadDTO.setIdRelacionFuenteEntidad(relacionFuenteEntidad.getIdRelacionFuenteEntidad().toString());
				relacionFuenteEntidadDTO.setIdReglaFuente(relacionFuenteEntidad.getIdReglaFuente().getIdReglaFuente().toString());
				relacionFuenteEntidadDTO.setId(contador2);
				relacionFuenteEntidadDTO.setItem(contador2);
				relacionFuenteEntidadDTO.setCampoEntidad(relacionFuenteEntidad.getCampoEntidad());
				relacionFuenteEntidadDTO.setIdCampoFuente(relacionFuenteEntidad.getIdDetalleFuente().getIdDetalleFuente().toString());
				relacionFuenteEntidadDTO.setCampoFuente(relacionFuenteEntidad.getCampoFuente());
				relacionFuenteEntidadDTO.setIdEstado(relacionFuenteEntidad.getIdEstado().getIdValor().toString());
				relacionFuenteEntidadDTO.setFueGuardado(true);
				listaDTO.add(relacionFuenteEntidadDTO);
			
				contador2++;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return listaDTO;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void eliminarRegla(Long idRegla) throws Exception{
		try {
			Regla regla = reglaDao.obtenerObjeto(idRegla,Regla.class);
			regla.setIdEstado(new Valor());
			regla.getIdEstado().setIdValor(ConstantesGenerales.EST_ELIMINADO_VALOR_LISTADO);
			reglaDao.actualizarObjeto(regla);
			List<ReglaFuente> listaReglaFuente = reglaFuenteDao.obtenerReglaFuente(regla.getIdRegla());
			for(ReglaFuente reglaFuente:listaReglaFuente){
				reglaFuente.setIdEstado(new Valor());
				reglaFuente.getIdEstado().setIdValor(ConstantesGenerales.EST_ELIMINADO_VALOR_LISTADO);
				reglaFuenteDao.actualizarObjeto(reglaFuente);
				List<RelacionFuenteEntidad> listaRelacionFuenteEntidad =  relacionFuenteEntidadDao.obtenerRelacionFuenteEntidad(reglaFuente.getIdReglaFuente());
				for(RelacionFuenteEntidad relacionFuenteEntidad:listaRelacionFuenteEntidad){
					relacionFuenteEntidad.setIdEstado(new Valor());
					relacionFuenteEntidad.getIdEstado().setIdValor(ConstantesGenerales.EST_ELIMINADO_VALOR_LISTADO);
					relacionFuenteEntidadDao.actualizarObjeto(relacionFuenteEntidad);
				}
			
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public Long obtenerTipoDeFuente(Long idFuente) throws Exception{
		Long tipoFuente = -1L;
		try {
			Fuente fuente = new Fuente();
			fuente = fuenteDao.obtenerObjeto(idFuente, Fuente.class);
			tipoFuente = fuente.getIdTipoFuente().getIdValor(); 
		} catch (Exception e) {
			e.printStackTrace();
		}
		return tipoFuente;
	}
	
	public Regla obtenerReglaPojo(Long idRegla) throws Exception{
		Regla regla = new Regla();
		try {
			regla = reglaDao.obtenerObjeto(idRegla, Regla.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return regla;
	}
}
